package edu.ccut.saturn.basecomponent.database.impl.mysql.builder;

import java.util.ArrayList;
import java.util.List;

import edu.ccut.saturn.basecomponent.database.ISaturnSQL;
import edu.ccut.saturn.basecomponent.database.SaturnSQLBuilderFactory;
import edu.ccut.saturn.basecomponent.database.impl.AbstractSelectSQLBuilder;
import edu.ccut.saturn.basecomponent.database.impl.SaturnSQL;
import edu.ccut.saturn.component.IDataInfo;
import edu.ccut.saturn.component.IDataItem;
import edu.ccut.saturn.component.SaturnDataManager;

public class MysqlSelectSQLBuilder extends AbstractSelectSQLBuilder {

	private static final String SQL_SELECT_PAGE = "SELECT * FROM(@resultSet@) A LIMIT ?,?";

	private static final String SQL_RESULTSET_PLACEHOLDER = "@resultSet@";

	/**
	 * 重写分页逻辑
	 */
	public ISaturnSQL build(String fullKey, String condition, int startIndex,
			int endIndex) throws Exception {
		return this.build(fullKey, condition, null, startIndex, endIndex);
	}
	
	/**
	 * 重写分区表分页逻辑
	 */
	public ISaturnSQL build(String fullKey, String condition, String tableWord,
			int startIndex, int endIndex) throws Exception {
		
		String sql = getSql(fullKey, condition, tableWord);

		SaturnSQL saturnsql = new SaturnSQL();
		saturnsql.setSql(sql);
		saturnsql.setDBtype(this.getDatabaseType());
		saturnsql.setOperationType(this.getOperationType());
		saturnsql.setSaturnData(null);
		saturnsql.setSaturnDataFullKey(fullKey);
		saturnsql.setStartIndex(startIndex);
		saturnsql.setEndIndex(endIndex-startIndex+1);

		return saturnsql;
	}

	private String getSql(String fullKey, String condition, String tableWord) {

		IDataInfo dataInfo = SaturnDataManager.getInstance().getSaturnDataInfo(
				fullKey);
		String sqlResult = SQL_SELECT_PAGE;
		String sql = getSqlSelect(condition, dataInfo, tableWord);
		sqlResult = sqlResult.replace(SQL_RESULTSET_PLACEHOLDER, sql);
		return sqlResult;
	}

	private String getSqlSelect(String condition, IDataInfo dataInfo, String tableWord) {
		StringBuffer sql = new StringBuffer();
		String tempSql = dataInfo.getSqlStr();

		if (tempSql != null && !"".equals(tempSql)) {
			sql.append(tempSql);

			if (condition != null) {
				sql.append(condition.replaceFirst("WHERE", " AND "));
			}
		} else {
			sql.append(" SELECT ");
			sql.append(getAfterSelectSql(dataInfo, tableWord));

			if (condition != null) {
				sql.append(condition);
			}
		}
		return sql.toString();
	}

	private StringBuffer getAfterSelectSql(IDataInfo dataInfo, String tableWord) {

		StringBuffer selectColumnName = new StringBuffer();
		StringBuffer selectTableName = new StringBuffer();
		List<String> tableNamelist = new ArrayList<String>();

		for (String key : dataInfo.keySet()) {

			IDataItem iDataItem = dataInfo.getDataItem(key);
			String colum = iDataItem.getColumn();
			String columnAlias = iDataItem.getColumnAlias();
			String tableName = iDataItem.getTableName();

			if (tableName != null && !"".equals(tableName.trim())) {
				selectColumnName.append(tableName).append(".").append(colum);

				if (columnAlias != null && !columnAlias.equals("")) {
					selectColumnName.append(" AS ").append(columnAlias).append(
							" ,");
				} else {
					selectColumnName.append(" ,");
				}
				if (tableWord != null) {
					continue;
				}
				if (!tableNamelist.contains(tableName)) {
					tableNamelist.add(tableName);
					selectTableName.append(tableName).append(" ,");
				}
			}
		}
		deleteLastCommaWithStringBuffer(selectColumnName);
		selectColumnName.append(" FROM ");
		deleteLastCommaWithStringBuffer(selectTableName);

		if (tableWord != null) {
			selectColumnName.append(tableWord).append(" ");
		} else {
			selectColumnName.append(selectTableName);
		}
		return selectColumnName;
	}

	private void deleteLastCommaWithStringBuffer(StringBuffer stringBuffer) {
		if (stringBuffer.length() != 0)
			stringBuffer.deleteCharAt(stringBuffer.length() - 1);
	}
	
	@Override
	protected String getDatabaseType() {
		return SaturnSQLBuilderFactory.MYSQL;
	}

	@Override
	protected String getOperationType() {
		return ISaturnSQL.SELECT_OPERATION;
	}
}
